var c = document.getElementById('c');
var ctx = c.getContext('2d');
c.width = window.innerWidth * window.devicePixelRatio;
c.height = window.innerHeight * window.devicePixelRatio;

function Ball(x, y, r, color, speed, a) {
    this.x = x || 0;
    this.y = y || 0;
    this.r = r || 0;
    this.color = color || '#fff';
    this.speed = speed || 1;
    this.a = a || .2;

    //加速度分解
    this.direction = 60;
    this.speedX = 1;
    this.speedY = 2;
    this.aX = 0;
    this.aY = 0;

    //重力加速度
    this.g = .2;
    this.bounce = -.8
}
Ball.prototype = {
    draw: function() {
        ctx.save();
        ctx.fillStyle = '#'+ this.color.toString(16);
        ctx.globalAlpha = .8;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }
}

//沿坐标轴方向加速度
function axisAcceleration() {
    var num = 3,
        i, balls = [];
    var r = Math.random() * 25 + 25;
    for(i = 0; i < num; i += 1) {
        balls.push(new Ball(
            r,
            Math.random() * (c.height - 100) + 100,
            Math.random() * r + 25,
            (Math.random() * 0xffffff) >> 0
        ))
    }

    function animate() {
        ctx.fillStyle = 'rgb(255, 255, 255)';
        ctx.fillRect(0, 0, c.width, c.height);

        var id = requestAnimationFrame(animate);

        for(var i = 0; i < num; i += 1) {
            balls[i].speed += balls[i].a; //速度每次加上加速度的值————匀加速运动
            balls[i].x += balls[i].speed;
            if(balls[i].x + balls[i].r >= c.width) {
                cancelAnimationFrame(id);
            }
            balls[i].draw();
        }
    }

    animate();
}

// axisAcceleration();

//加速的合成与分解
function decomposeAcceleration() {
    var ball = new Ball(100, 100, 50, (Math.random() * 0xffffff) >> 0);

    function animate() {
        ctx.fillStyle = '#fff';
        ctx.fillRect(0, 0, c.width, c.height);

        ball.aX = Math.cos(ball.direction * Math.PI / 180) * ball.a;
        ball.aY = Math.sin(ball.direction * Math.PI / 180) * ball.a;

        ball.speedX += ball.aX;
        ball.speedY += ball.aY;

        ball.x += ball.speedX;
        ball.y += ball.speedY;
        ball.draw();
        var id = requestAnimationFrame(animate);
        if(ball.y + ball.r >= c.height) {
            ball.y = c.height;
            cancelAnimationFrame(id);
        }
    }

    animate();
}

// decomposeAcceleration();

//重力加速度
function gravity() {
    var ball = new Ball(c.width / 2, c.height / 2 - 200, 50, (Math.random() * 0xffffff) >> 0);

    //触底边检测
    function checkBottom(ball) {
        if(ball.y + ball.r >= c.height) {
            ball.y = c.height - ball.r;
            ball.speed *= ball.bounce;
        }
    }

    function animate() {
        requestAnimationFrame(animate);
        ctx.fillStyle = 'rgb(255, 255, 255)';
        ctx.fillRect(0, 0, c.width, c.height);

        ball.speed += ball.g;
        ball.y += ball.speed;
        checkBottom(ball);
        ball.draw();
    }

    animate();
}

// gravity();

function createShip() {
    var curShip;

    //矢量类
    function Vector(x, y) {
        this.x = x || 0;
        this.y = y || 0;
    }
    Vector.add = function(a, b) {
        return new Vector(a.x + b.x, a.y + b.y);
    }
    Vector.sub = function(a, b) {
        return new Vector(a.x - b.x, a.y - b.y);
    }
    Vector.random = function() {
        return new Vector(
            Math.random() * 2 - 1,
            Math.random() * 2 - 1
        );
    }
    Vector.prototype = {
        set: function(x, y) {
            if(typeof x === 'object') {
                x = x.x;
                y = x.y;
            }
            this.x = x || 0;
            this.y = y || 0;
            return this;
        },
        add: function(b) {
            this.x += b.x;
            this.y += b.y;
            return this;
        },
        sub: function(b) {
            this.x -= b.x;
            this.y -= b.y;
            return this;
        },
        scale: function(b) {
            this.x *= b.x;
            this.y *= b.y;
            return this;
        },
        lenght: function() {
            return Math.sqrt(this.x * this.x + this.y * this.y);
        },
        lengthTo: function(v) {
            var dx = v.x - this.x,
                dy = v.y - this.y;
            return Math.sqrt(dx * dx + dy * dy);
        },
        lenghtSq: function() {
            return this.x * this.x + this.y * this.y;
        },
        lengthToSq: function() {
            var dx = v.x - this.x,
                dy = v.y - this.y;
            return dx * dx + dy * dy;
        },
        normalize: function() {
            var m = Math.sqrt(this.x * this.x + this.y * this.y);
            if(m) {
                this.x /= m;
                this.y /= m;
            }
            return this;
        },
        angle: function() {
            return Math.atan2(this.x, this.y);
        },
        angleTo: function(v) {
            var dx = v.x - this.x,
                dy = v.y - this.y;
            return Math.atan2(dy, dx);
        },
        lerp: function(v, t) {
            this.x += (v.x - this.x) * t;
            this.y += (v.y - this.y) * t;
            return this;
        },
        clone: function() {
            return new Vector(this.x, this.y);
        },
        toString: function() {
            return '(x:' + this.x + ', y:' + this.y + ')';
        }
    }

    function Ship(x, y, speed, direction, acceleration, maxSpeed, isQuickening) {
        //继承自Vector
        if(curShip) {
            return curShip;
        } else {
            Vector.call(this, x, y);
            this.speed = {
                x: speed.x || 1,
                y: speed.y || 1
            }; //当前速度
            this.maxSpeed = maxSpeed || 10; //最大速度
            this.direction = direction || 0; //移动方向角度
            this.a = {
                total: acceleration || .1,
                x: 0,
                y: 0
            }; //当前加速度
            this.damping = .8; //加速度衰减系数
            this.isQuickening = isQuickening || false;
            curShip = this;
        }
    }
    Ship.prototype = (function(o){
        var p = {}, key;
        for(key in o) {
            if(o.hasOwnProperty(key)) {
                p[key] = o[key]
            }
        };
        return p;
    })(Vector.prototype);
    Ship.prototype.draw = function() {
        ctx.save();
        ctx.translate(this.x, this.y);
        ctx.rotate(this.direction);
        ctx.strokeStyle = 'white';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(25, 0);
        ctx.lineTo(-10, -15);
        ctx.lineTo(0, 0);
        ctx.lineTo(-10, 15);
        ctx.closePath();
        ctx.stroke();
        if(this.isQuickening) {
            ctx.strokeStyle = 'red';
            ctx.beginPath();
            ctx.lineTo(20, 0);
            ctx.moveTo(-5, 5);
            ctx.lineTo(-20, 0);
            ctx.lineTo(-5, -5);
            ctx.stroke();
        }
        ctx.restore();
    }

    var ship = new Ship(
        c.width / 2,
        c.height / 2,
        {x: .1, y: .1},
        0,
        .5,
        10,
        false
    );
    var vr = 0;

    //绑定事件
    document.addEventListener('keydown', function(e) {
        var event = e || window.event;
        switch(event.key) {
            case 'ArrowUp': handleArrowUp(); break;
            case 'ArrowLeft': handleArrowLeft(); break;
            case 'ArrowRight': handleArrowRight(); break;
            default: break;
        }
        return false;
    });
    document.addEventListener('keyup', function() {
        ship.isQuickening = false;
    });

    //上箭头处理函数
    function handleArrowUp() {
        ship.isQuickening = true;
        ship.a.x = Math.cos(ship.direction) * ship.a.total;
        ship.a.y = Math.sin(ship.direction) * ship.a.total;

        ship.speed.x += ship.a.x;
        ship.speed.y += ship.a.y;

        ship.add(ship.speed);
    }

    //右箭头处理函数
    function handleArrowRight() {
        vr = 2;
        ship.direction += vr * (Math.PI / 180);
        ship.speed.x = 0;
        ship.speed.y = 0;
    }

    //左箭头处理函数
    function handleArrowLeft() {
        vr = -2;
        ship.direction += vr * (Math.PI / 180);
        ship.speed.x = 0;
        ship.speed.y = 0;
    }

    function animate() {
        requestAnimationFrame(animate);
        ctx.fillStyle = '#000';
        ctx.fillRect(0, 0, c.width, c.height);
        ship.draw();
    }

    animate();
}

createShip();